﻿using Kingdee.BOS;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.Core;
using Kingdee.BOS.Core.CommonFilter;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.DynamicForm.PlugIn.ControlModel;
using Kingdee.BOS.Core.Metadata.EntityElement;
using Kingdee.BOS.Core.Metadata.FieldElement;
using Kingdee.BOS.Core.Report;
using Kingdee.BOS.JSON;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Util;
using Kingdee.BOS.WebApi.FormService;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;

namespace WSDZ.KM.ZH.AttachmentUploadForm3
{
    [Description("附件上传表单插件"), HotUpdate]
    public class UploadForm : AbstractDynamicFormPlugIn
    {
        public string btype = "附件上传表单插件";
        public string currentFormId = string.Empty;
        public string matFormId { get; set; } = "BD_MATERIAL";
        public const string FileUploadServicesDir = "FileUploadServices/UploadFiles";
        /// <summary>
        /// 文件信息
        /// </summary>
        List<FileData> FileList = new List<FileData>();
        /// <summary>
        /// 文件单据体
        /// </summary>
        public string filekey = "FFileEntity";
        public override void AfterBindData(EventArgs e)
        {
            base.AfterBindData(e);
            currentFormId = View.BillBusinessInfo.GetForm().Id;
        }
        public override void ButtonClick(ButtonClickEventArgs e)
        {
            base.ButtonClick(e);
            if (e.Key.EqualsV1("F_Submit"))
            {
                try
                {
                    SubmitInvoke();
                }
                catch (Exception ex)
                {
                    View.ShowErrMessage(ex.Message);
                }
            }
            //导出
            else if (e.Key.EqualsV1("F_Export"))
            {
                try
                {
                    EntryEntity entryEntity = this.View.BillBusinessInfo.GetEntryEntity(filekey);
                    DynamicObjectCollection entrys = this.Model.GetEntityDataObject(entryEntity);
                    if (entrys != null && entrys.Count > 0)
                    {
                        string[] keyStrs = { "FSaleOrgId_Id" };
                        List<Field> keys = entryEntity.Fields;
                        keys.RemoveAll(x => keyStrs.Contains(x.Key));//移除基础资料的ID字段
                        string tempFilePath = HttpContext.Current.Server.MapPath(KeyConst.TEMPFILEPATH);
                        string filePath = Path.Combine(tempFilePath, DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx"); //用GUID做文件名，防止同名冲突。
                        Export(entrys, keys, filePath);
                        string fileName = Path.GetFileName(filePath);
                        string fileUrl = PathUtils.GetServerPath("tempfilePath", fileName);
                        DynamicFormShowParameter param = new DynamicFormShowParameter();
                        param.FormId = "BOS_FileDownLoad";
                        param.OpenStyle.ShowType = ShowType.Modal;
                        param.CustomParams.Add("IsExportData", "true");
                        param.CustomParams.Add("url", fileUrl);
                        this.View.ShowForm(param);
                    }
                }
                catch (Exception ex)
                {
                    View.ShowErrMessage(ex.Message);
                }

            }
        }
        public override void AfterEntryBarItemClick(AfterBarItemClickEventArgs e)
        {
            base.AfterEntryBarItemClick(e);
            if (e.BarItemKey.EqualsV1("btnDeleteRow"))
            {
                try
                {
                    Entity entity = this.Model.BillBusinessInfo.GetEntity(filekey);
                    DynamicObjectCollection rows = this.Model.GetEntityDataObject(entity);
                    if (rows!=null&&rows.Count>0)
                    {
                        //var selectrows = rows.Where(x => x["Fischeck"].ToBoolean()).Select(x => new {
                        //    seq = x["seq"].ToStringV1().ToInt32V1(),
                        //    guid=x["Fguid"].ToStringV1()
                        //}).ToList();
                        //foreach (var item in selectrows)
                        //{
                        //    Model.DeleteEntryRow(filekey,item.seq-1);
                        //    FileList.RemoveAll(x=>x.Guid.Equals(item.guid));
                        //}
                        //View.UpdateView(filekey);
                        List<string> guidList = rows.Where(x => x["Fischeck"].ToBoolean()).Select(x => x["Fguid"].ToStringV1()).ToList();
                        FileList.RemoveAll(x=>guidList.Contains(x.Guid));
                        FillFileEntry();
                    }

                }
                catch (Exception ex)
                {
                    View.ShowErrMessage(ex.Message);
                }
            }
        }
        public override void CustomEvents(CustomEventsArgs e)
        {
            base.CustomEvents(e);
            //上传文件
            if (e.Key.EqualsV1("F_Attachment"))
            {
                try
                {
                    View.GetControl("F_Attachment").SetCustomPropertyValue("NeedCallback", true);
                    View.GetControl("F_Attachment").SetCustomPropertyValue("IsRequesting", false);
                    if (e.EventName.EqualsIgnoreCase("FileChanged"))
                    {
                        //FileList = new List<FileData>();
                        if (FileList==null)
                        {
                            FileList = new List<FileData>();
                        }
                        //View.UpdateView(filekey);
                        var postData = KDObjectConverter.DeserializeObject<JSONObject>(e.EventArgs);
                        if (postData!=null)
                        {
                            JSONArray uploadInfo = new JSONArray(postData["NewValue"].ToString());
                            if (uploadInfo.Count>0)
                            {
                                //List<FileData> flist = uploadInfo.Select(x =>
                                //{
                                //    var fileInfo = x as Dictionary<string, object>;
                                //    FileData fdata = new FileData();
                                //    fdata.Guid = Guid.NewGuid().ToStringV1();
                                //    fdata.FileName = fileInfo["FileName"].ToStringV1();
                                //    fdata.ServerFileName = fileInfo["ServerFileName"].ToStringV1();
                                //    fdata.FullPath = PathUtils.GetPhysicalPath(FileUploadServicesDir, fileInfo["ServerFileName"].ToStringV1());
                                //    fdata.FileLength = fileInfo["FileLength"].ToStringV1().ToLong();
                                //    fdata.FileBytesLength = fileInfo["FileBytesLength"].ToStringV1().ToLong();
                                //    return fdata;
                                //}).ToList();
                                foreach (var item in uploadInfo)
                                {
                                    var fileInfo = item as Dictionary<string, object>;
                                    string FileName = fileInfo["FileName"].ToStringV1();
                                    var obj = FileList.Where(x => x.FileName.Equals(FileName)).FirstOrDefault();
                                    if (obj==null)
                                    {
                                        FileData fdata = new FileData();
                                        fdata.Guid = Guid.NewGuid().ToStringV1();
                                        fdata.FileName = FileName;
                                        fdata.ServerFileName = fileInfo["ServerFileName"].ToStringV1();
                                        fdata.FullPath = PathUtils.GetPhysicalPath(FileUploadServicesDir, fileInfo["ServerFileName"].ToStringV1());
                                        fdata.FileLength = fileInfo["FileLength"].ToStringV1().ToLong();
                                        fdata.FileBytesLength = fileInfo["FileBytesLength"].ToStringV1().ToLong();
                                        FileList.Add(fdata);
                                    }
                                }

                            }
                            View.GetControl("F_Attachment").SetValue(null);
                            View.UpdateView("F_Attachment");
                        }
                        FillFileEntry();
                    }
        


                }
                catch (Exception ex)
                {
                    View.ShowErrMessage(ex.Message);
                }
            }

        }
    
       
        public void FillFileEntry()
        {
            Model.DeleteEntryData(filekey);
            if (FileList==null|| FileList.Count<1)
                return;
            Entity entity = this.Model.BillBusinessInfo.GetEntity(filekey);
            DynamicObjectCollection rows = this.Model.GetEntityDataObject(entity);
            int seq = 1;
            foreach (var data in FileList)
            {
                DynamicObject row = new DynamicObject(entity.DynamicObjectType);
                entity.SeqDynamicProperty.SetValue(row, seq);
                row["Fguid"] = data.Guid;
                row["FFileName"] = data.FileName;
                row["FServerFileName"] = data.ServerFileName;
                row["FFullPath"] = data.FullPath;
                row["FFileLength"] = data.FileLength;
                row["FFileBytesLength"] = data.FileBytesLength;
                row["Fresult"] = data.result.ToStringV1();
                rows.Add(row);
                seq++;
            }
            View.UpdateView(filekey);
        }


        public void SubmitInvoke()
        {
            if (FileList.Count<1)
            {
                View.ShowErrMessage("文件数量不可为空!!!");
                return;
            }
            FileList = FileList.Select(x =>
            {
                x.Name = Path.GetFileNameWithoutExtension(x.FileName);
                if (x.Name.Contains("_"))
                {
                    x.Name = x.Name.Split('_')[0].ToStringV1();
                }
                return x;
            }).ToList();

            List<BillData> matList = new List<BillData>();
            int size = 2000;
            int icount = FileList.Count <= size ? 1 : FileList.Count % size > 0 ? FileList.Count / size + 1 : FileList.Count / size;
            for (int i = 0; i < icount; i++)
            {
                List<string> numbers = FileList.Skip(i * size).Take(size).Select(x => x.Name).Distinct().ToList();
                string sql_mat = $@"select 
Id=mat.FMATERIALID
,Number=mat.FNUMBER
from T_BD_MATERIAL mat 
where mat.FNumber in ('{string.Join("','",numbers)}')";
                DynamicObjectCollection datas = DBUtils.ExecuteDynamicObject(Context,sql_mat);
                if (datas!=null)
                {
                    List<BillData> blist = datas.DynamicObjectCollectionToDataList<BillData>();
                    matList.AddRange(blist);
                }
            }
            for (int i = 0; i < FileList.Count; i++)
            {
                FileData fobj = FileList[i];
                try
                {
                    int matId = 0;
                    string matNumber = fobj.Name;
                    var matObj = matList.Where(x => x.Number.EqualsV1(matNumber)).FirstOrDefault();
                    if (matObj != null)
                        matId = matObj.Id;
                    if (matId == 0)
                    {
                        fobj.result = "未找到对应单据,请检查编码是否正确";
                        continue;
                    }
                    int fjCount = DBUtils.ExecuteScalar<int>(Context,$@"select 1 from T_BAS_ATTACHMENT
where FBILLTYPE='BD_Material'
and FINTERID={matId} and FATTACHMENTNAME=@FATTACHMENTNAME",0,new SqlParam("@FATTACHMENTNAME",KDDbType.String,fobj.FileName));
                    if (fjCount>0)
                    {
                        fobj.result = "该附件已存在";
                        continue;
                    }
                    string base64Str = "";
                    var baseObj = UtilityManager.DocumentToBase64(fobj.FullPath);
                    if (baseObj.Item1)
                        base64Str = baseObj.Item3;
                    else
                    {
                        fobj.result = baseObj.Item2;
                        continue;
                    }
                    JObject Root = new JObject();
                    Root["FileName"] = fobj.FileName;
                    Root["FormId"] = matFormId;
                    Root["IsLast"] = true;
                    //单据ID
                    Root["InterId"] = matId;
                    Root["BillNO"] = matNumber;
                    Root["SendByte"] = base64Str;
                    string json = Root.ToStringV1();
                    string msg = string.Empty;
                    bool isok = FormApiHelper.AttachmentUpload(Context, json, ref msg);
                    if (isok)
                        fobj.result = "成功";
                    else
                        fobj.result = msg;

                }
                catch (Exception ex)
                {
                    fobj.result = $@"异常【{ex.Message}】";
                    continue;
                }
                

            }
            Model.DeleteEntryData(filekey);
            View.UpdateView(filekey);
            FillFileEntry();
        }
        XSSFWorkbook workbook = new XSSFWorkbook();
        public void Export(DynamicObjectCollection colls, List<Field> keys, string filePath)
        {
            workbook = new XSSFWorkbook();
            FillSheet_basicInfo(colls, keys);
            //转为字节数组  
            MemoryStream stream = new MemoryStream();
            workbook.Write(stream);
            var buf = stream.ToArray();
            //保存为Excel文件  
            using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
            {
                fs.Write(buf, 0, buf.Length);
                fs.Flush();
            }
        }
        public void FillSheet_basicInfo(DynamicObjectCollection colls, List<Field> keys)
        {
            //ICellStyle cellStyle = CreateStyle();
            int counts = keys.Count;
            //string[] keyStr = { "FSaleOrgId", "FPROMOTERS" };//基础资料字段需特殊处理
            string[] keyStr = { "" };//基础资料字段需特殊处理
            //创建工作表
            XSSFSheet sheet = (XSSFSheet)workbook.CreateSheet("附件上传结果");
            sheet.DefaultColumnWidth = 20;
            sheet.DefaultRowHeight = 30 * 20;
            ////创建表头（第一行）
            //XSSFRow rowHeader = (XSSFRow)sheet.CreateRow(0);
            //sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, counts - 1));
            //for (int i = 0; i < counts; i++)
            //{
            //    sheet.SetColumnWidth(i, 20 * 100);
            //}
            //XSSFCell cellHeader = (XSSFCell)rowHeader.CreateCell(0);
            //cellHeader.CellStyle = cellStyle;
            ////rowHeader.Height = 30 * 20;
            //cellHeader.SetCellValue("基本信息");
            //创建列名（第二行）
            XSSFRow rowColumn = (XSSFRow)sheet.CreateRow(0);
            for (int j = 0; j < counts; j++)
            {
                XSSFCell cellColumn = (XSSFCell)rowColumn.CreateCell(j);
                cellColumn.SetCellValue(keys[j].Name.ToStringV1());
            }
            //创建数据行
            for (int c = 0; c < colls.Count; c++)
            {
                DynamicObject col = colls[c];
                XSSFRow rowData = (XSSFRow)sheet.CreateRow(c + 1);
                for (int a = 0; a < counts; a++)
                {
                    string key = keys[a].Key;
                    string value = string.Empty;
                    if (keyStr.Contains(key))
                    {
                        try
                        {
                            object obj1 = col.GetValue(key);
                            object name = ((dynamic)obj1).Name;
                            value = name.ToStringV1();
                        }
                        catch (Exception)
                        {
                            value = "";
                        }
                    }
                    else
                    {
                        value = col.GetValue(key).ToStringV1();
                        value = value.ToUpper() == "true".ToUpper() ? "是" : value.ToUpper() == "false".ToUpper() ? "否" : value;
                    }
                    XSSFCell cellData = (XSSFCell)rowData.CreateCell(a);
                    cellData.SetCellValue(value);
                }
            }
        }
    }

    public class FileData
    {
        public string Guid { get; set; }
        public string Name { get; set; }
        public string FileName { get; set; }
        public string ServerFileName { get; set; }
        public string FullPath { get; set; }
        public long FileLength { get; set; }
        public long FileBytesLength { get; set; }
        public string result { get; set; }

    }
   
    public class BillData
    {
        public int Id { get; set; }
        public string Number { get; set; }
    }
}
